using DimensionsHelper.LanguageService.Symbols;
using DimensionsHelper.LanguageService.Syntax;

namespace DimensionsHelper.LanguageService;

public class AnalysisBinary : AnalysisExpression
{
    internal AnalysisBinary(
        BinaryExpression syntaxNode,
        AnalysisNode? parent,
        AnalysisExpression left,
        AnalysisExpression right) :
        base(AnalysisBoundKinds.Binary, syntaxNode, parent)
    {
        Syntax = syntaxNode;

        Left = left;
        Left.Parent = this;

        Right = right;
        Right.Parent = this;
    }


    public override BinaryExpression Syntax { get; }

    public AnalysisExpression Left { get; }

    public AnalysisExpression Right { get; }


    public override IEnumerable<AnalysisNode> GetChildren()
    {
        return [Left, Right];
    }

    internal override void AddChild(AnalysisNode child)
    {
        throw new NotSupportedException("AnalysisBinary is read-only.");
    }

    public override AnalysisExpression? WithImplicitlyConversion(ValueTypeSymbol targetType)
    {
        // 调用此方法时，应当已经绑定了此表达式的类型符号，如果未绑定符号，
        // 此方法不可调用，直接返回 null
        ISymbol symbol = GetSymbol();
        if (symbol.IsUndefined)
        {
            return null;
        }

        return targetType.IsAssignableFrom((ITypeSymbol)symbol) ? this : null;
    }
}

public static partial class AnalysisNodeFactory
{
    /// <summary>
    /// 创建一个二元表达式
    /// </summary>
    /// <param name="syntaxNode">原始语法节点</param>
    /// <param name="parent">父节点，可以忽略</param>
    /// <param name="left">左值表达式</param>
    /// <param name="right">右值表达式</param>
    /// <param name="withSymbol">语法节点所在的With语句上下文类型符号</param>
    public static AnalysisBinary Binary(BinaryExpression syntaxNode,
        AnalysisNode? parent,
        AnalysisExpression left,
        AnalysisExpression right,
        ITypeSymbol? withSymbol)
    {
        return new AnalysisBinary(syntaxNode, parent, left, right).WithContainingWithSymbol(withSymbol);
    }
}
